/* eslint-disable no-array-constructor */
/* eslint-disable no-undef */
/* eslint-disable no-new-object */
/* eslint-disable eqeqeq */
/* eslint-disable no-tabs */
/* eslint-disable no-mixed-spaces-and-tabs */
var nmCryptokit = {
	// Release path: \\192.168.117.2\Release\SADK\Client\ZHY\CryptoKit
	chromeExtension: "hikdaibcmjjchlpicncdflhglhokiipi",
	edgeExtension: "ppobibpaffkpcpjcgkpmecdpbdpeehok",
	productID: "com.cfca.cryptokit.induschain",
	// extensionName: nmCryptokit.productID + ".extension",
	// reqEventName: nmCryptokit.productID + ".request",
	// respEventName: nmCryptokit.productID + ".response",

	Browser: {
		IE: "Internet Explorer",
		Edge: "Edge",
		Edg: "Edge(Chromium)",
		Chrome: "Chrome",
		Safari: "Safari",
		Firefox: "Firefox",
	},

	// Encapsulate Chrome sendMessage callback to Promise
	_SendMessageforChrome: function (request) {
		let self = this;
		return new Promise(function (resolve, reject) {
			// eslint-disable-next-line no-undef
			chrome.runtime.sendMessage(
				self.chromeExtension,
				request,
				function (response) {
					if (response) {
						// eslint-disable-next-line eqeqeq
						if (response.errorcode == 0) {
							resolve(response);
						} else {
							reject(response);
						}
					} else {
						// eslint-disable-next-line no-new-object
						let result = new Object();
						result.errorcode = 1;
						// eslint-disable-next-line no-undef
						result.result = chrome.runtime.lastError.message;
						reject(result);
					}
				}
			);
		});
	},

	// Encapsulate Chrome sendMessage callback to Promise
	_SendMessageforEdge: function (request) {
		let self = this;
		return new Promise(function (resolve, reject) {
			// eslint-disable-next-line no-undef
			chrome.runtime.sendMessage(
				self.edgeExtension,
				request,
				function (response) {
					if (response) {
						// eslint-disable-next-line eqeqeq
						if (response.errorcode == 0) {
							resolve(response);
						} else {
							reject(response);
						}
					} else {
						// eslint-disable-next-line no-new-object
						let result = new Object();
						result.errorcode = 1;
						// eslint-disable-next-line no-undef
						result.result = chrome.runtime.lastError.message;
						reject(result);
					}
				}
			);
		});
	},

	// Encapsulate Edge&Firefox event to Promise
	_SendMessagebyEvent: function (request) {
		let self = this;
		let event = new CustomEvent(self.reqEventName, { detail: request });
		document.dispatchEvent(event);

		return new Promise(function (resolve, reject) {
			// document.addEventListener(
			// 	self.respEventName,
			// 	function CallBack(e) {
			// 		document.removeEventListener(e.type, CallBack);
			// 		var eJson = JSON.parse(e.detail);
			// 		if (eJson != null && eJson.errorcode == 0) {
			// 			resolve(eJson);
			// 		} else {
			// 			reject(eJson);
			// 		}
			// 	},
			// 	false
			// );
			let responseEventName = nmCryptokit.respEventName;
			if (
				request.funcInfo != undefined &&
				request.funcInfo.randomId != undefined
			) {responseEventName += "." + request.funcInfo.randomId}

			document.addEventListener(
				responseEventName,
				function CallBack(e) {
					document.removeEventListener(e.type, CallBack);
					let eJson = JSON.parse(e.detail);
					if (null != eJson && 0 == eJson.errorcode) {
						resolve(eJson);
					} else {
						reject(eJson);
					}
				},
				false
			);
		});
	},

	_SendMessage: function (browser, requestJSON) {
		let self = this;
		if (self.Browser.Chrome == browser) {
			return self._SendMessageforChrome(requestJSON);
		} else if (self.Browser.Edg == browser) {
			return nmCryptokit._SendMessageforEdge(requestJSON);
		} 
			return self._SendMessagebyEvent(requestJSON);
	},

	_checkExtension: function (browser) {
		let self = this;
		return new Promise(function (resolve, reject) {
			let result = new Object();
			if (self.Browser.Chrome == browser || self.Browser.Edg == browser) {
				// chrome.runtime.sendMessage() could check extension  existence.
				if (chrome.runtime) {
					resolve(browser);
				} else {
					result.errorcode = 2;
					result.result = "Extension does not exist!";
					reject(result);
				}
			} else if (
				self.Browser.Edge == browser ||
				self.Browser.Firefox == browser
			) {
				if (document.getElementById(self.extensionName)) {
					resolve(browser);
				} else {
					result.errorcode = 2;
					result.result = "Extension does not exist!";
					reject(result);
				}
			} else {
				result.errorcode = 3;
				result.result = "Only support Chrome Firefox and Edge";
				reject(result);
			}
		});
	},

	init: function (browser) {
		let self = this;

		this.browser = browser;
		this.extensionName = this.productID + ".extension";
		this.reqEventName = this.productID + ".request";
		this.respEventName = this.productID + ".response";

		return self
			._checkExtension(browser)
			.then(function (browser) {
				let request = new Object();
				request.action = "connect";
				request.host = self.productID;
				return self._SendMessage(browser, request);
			})
			.then(function () {
				// var request = new Object();
				// request.action = "checkHost";
				// return self._SendMessage(browser, request);
				let request = new Object();
				let funcInfo = new Object();
				funcInfo.function = "checkHost";
				funcInfo.params = null;
				request.action = "invoke";
				request.funcInfo = funcInfo;
				return self._SendMessage(browser, request);
			});
	},

	uninit: function () {
		let self = this;
		let request = new Object();
		request.action = "disconnect";
		request.host = self.productID;

		return self._SendMessage(this.browser, request);
	},

	getExtensionVersion: function () {
		let self = this;
		let request = new Object();
		let funcInfo = new Object();

		funcInfo.function = "getExtensionVersion";
		funcInfo.params = null;
		request.action = "getExtensionVersion";
		request.funcInfo = funcInfo;

		return self._SendMessage(this.browser, request);
	},

	// 新增
	getHostVersion: function () {
		let self = this;
		let request = new Object();
		let funcInfo = new Object();
		let randomId = GenerateRandomId();

		funcInfo.function = "GetVersion";
		funcInfo.params = null;
		funcInfo.randomId = randomId;

		request.action = "invoke";
		request.funcInfo = funcInfo;

		return self._SendMessage(this.browser, request);
	},

	selectCertificate: function (
		bstrSubjectDNFilter,
		bstrIssuerDNFilter,
		bstrSerialNumFilter,
		bstrCSPNameList
	) {
		let self = this;
		let request = new Object();
		let funcInfo = new Object();
		let paramArr = [];
		let randomId = GenerateRandomId();

		paramArr.push(bstrSubjectDNFilter);
		paramArr.push(bstrIssuerDNFilter);
		paramArr.push(bstrSerialNumFilter);
		paramArr.push(bstrCSPNameList);

		funcInfo.function = "selectCertificate";
		funcInfo.params = paramArr;
		console.log("方法selectCertificate", funcInfo.params);
		funcInfo.randomId = randomId;

		request.action = "invoke";
		request.funcInfo = funcInfo;

		return self._SendMessage(this.browser, request);
	},

	getSignCertInfo: function (bstrInfoType) {
		let self = this;
		let request = new Object();
		let funcInfo = new Object();
		let paramArr = [];
		let randomId = GenerateRandomId();

		paramArr.push(bstrInfoType);

		funcInfo.function = "GetSignCertInfo";
		funcInfo.params = paramArr;
		funcInfo.randomId = randomId;

		request.action = "invoke";
		request.funcInfo = funcInfo;

		return self._SendMessage(this.browser, request);
	},

	signMsgPKCS7: function (bstrSourceData, bstrHashAlg, bWithSourceData) {
		let self = this;
		let request = new Object();
		let funcInfo = new Object();
		let paramArr = [];
		let randomId = GenerateRandomId();

		paramArr.push(bstrSourceData);
		paramArr.push(bstrHashAlg);
		paramArr.push(bWithSourceData);

		funcInfo.function = "signMsgPKCS7";
		funcInfo.params = paramArr;
		funcInfo.randomId = randomId;

		request.action = "invoke";
		request.funcInfo = funcInfo;

		return self._SendMessage(this.browser, request);
	},

	getLastErrorDesc: function () {
		let self = this;
		let request = new Object();
		let funcInfo = new Object();
		let randomId = GenerateRandomId();

		funcInfo.function = "GetLastErrorDesc";
		funcInfo.params = null;

		request.action = "invoke";
		request.funcInfo = funcInfo;

		return self._SendMessage(this.browser, request);
	},

	signHashMsgPKCS7Detached: function (bstrSourceData, bstrHashAlg) {
		let self = this;
		let request = new Object();
		let funcInfo = new Object();
		let paramArr = [];
		let randomId = GenerateRandomId();

		paramArr.push(bstrSourceData);
		paramArr.push(bstrHashAlg);

		funcInfo.function = "SignHashMsgPKCS7Detached";
		funcInfo.params = paramArr;
		funcInfo.randomId = randomId;

		request.action = "invoke";
		request.funcInfo = funcInfo;

		return self._SendMessage(this.browser, request);
	},
};
export { nmCryptokit };

export function GenerateRandomId() {
	let charstring =
		"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
	let maxPos = charstring.length;
	let randomId = "";
	for (let i = 0; i < 10; i++) {
		randomId += charstring.charAt(Math.floor(Math.random() * maxPos));
	}
	return randomId;
}
